<?php
namespace app\nadmin\controller;
use think\console\command\make\Controller;
use think\db;
/**
 * @explain 生成数据库操作类
 * @time 2019-3-22
 * @writer liuhao
 */

class Createinit extends Controller
{
    //创建数据表的SQL存放文件路径
    protected $tableSQLFile;
    //菜单SQL地址
    protected $menuSQLFile;
    public $now;
    protected $username ='adminer' ; //默认管理员账号
    protected $pwd = 'adminer';//默认管理员密码
    //错误提示
    protected $errorMsg = "";

    public function __construct()
    {
        parent::__construct();
        $this->now= date('Y-m-d H:i:s',time());
        //数据表SQL地址
        $this->tableSQLFile = dirname(dirname(__FILE__))."/vendor/tableSql.php";
        //菜单SQL地址
        $this->menuSQLFile = dirname(dirname(__FILE__))."/vendor/menuSql.php";
    }

    public function __set($name, $value)
    {
        if(isset($this->$name))
        {
            $this->$name = $value;
        }
    }

    public function __get($name)
    {
        if(isset($this->$name)){
            return $this->$name;
        }
        return false;
    }

    //生成初始化
    public function createInit()
    {

        //检测是否允许生成
        if(false === $this->isAgree())
        {
            $this->errorMsg = "未经允许初始化";
            return false;
        };

        //创建数据表
        $tableSQLArr = $this->includeSQL();

        if(empty($tableSQLArr))
        {

            $this->errorMsg = "没有找到创建表所需的SQL文件";
            return false;

        }

        if(is_array($tableSQLArr))
        {
            //查看是否有表前缀
            $prefix = $this->getPrefix();
            foreach($tableSQLArr as $k=>$v)
            {
                //拼接SQL
                $v = $this->joinTableSQL($k,$v,$prefix);
                Db::execute($v);
            }

        }else
        {
            $this->errorMsg = "创建表所需的SQL文件格式错误";
            return false;
        }

        //生成菜单权限数据
        $re = $this->createMenu();
        if(!$re)
        {
            //菜单写入失败
            return false;
        }

        //生成角色
        $roleId =Db::name('role')->insertGetId($this->roleSQLData());

        //生成一个超级管理员
        if($roleId){
            //查看是否存在该管理员
            $re = Db::name("adminer")->field("id")->where("username='{$this->username}'")->find();
            if($re['id'])
            {
                $this->errorMsg = "该管理员账号已存在";
                return false;
            }

            $adminId = Db::name('adminer')->insertGetId($this->adminerSQLData($roleId));
            if($adminId)
            {
                $this->createIsGree();
                return true;
            }else{
                $this->errorMsg = "生成管理员失败";
                return false;
            }
        }else{
            $this->errorMsg = "生成角色失败";
            return false;
        }

    }

    //加载创建表数据
    protected function includeSQL()
    {
        if(file_exists($this->tableSQLFile)){
            $tableTableSQL = include($this->tableSQLFile);
            return $tableTableSQL;
        }else{
            return "";
        }
    }

    //系统生成角色SQL数据
    protected function roleSQLData()
    {
        $ids = $this->selectMenuIds(); //菜单权限集合
        return ['role'=>'超级管理员','status'=>1,'menu_ids'=>$ids];
    }

    //读取所有菜单的id
    protected function selectMenuIds()
    {
        $re = Db::name("menu")->field("GROUP_CONCAT(id) as ids")->find();
        $ids = isset($re['ids'])?$re['ids']:'';
        return $ids;
    }

    //系统生成菜单SQL数据
    protected function createMenu()
    {

        if(file_exists($this->menuSQLFile))
        {
            $menuSQL = include_once $this->menuSQLFile;
            if(is_array($menuSQL) && $menuSQL)
            {
                /*foreach($menuSQL as &$v)
                {
                    if(!$v['ctime']) $v['ctime'] = $this->now;
                    //写入
                    $re = Db::name("menu")->insert($v);
                }*/
                $this->recursion($menuSQL,0);

                return true;

            }
            $this->errorMsg = "菜单SQL为空或数据格式错误";
            return false;
        }
        $this->errorMsg = "菜单SQL地址错误";
        return false;
    }

    //系统生成管理员数据
    protected function adminerSQLData($role_id)
    {

        if(is_numeric($role_id))
        {
            $salt = getRandStr($num=6,$str='');
            //密码
            $pwd = createPwd($this->pwd,$salt);
            $salt = $salt;
            return ['role_id'=>$role_id,'username'=>$this->username,'pwd'=>$pwd,'status'=>1,'ctime'=>$this->now,'salt'=>$salt];
        }else{
            return false;
        }

    }

    //检测是否允许生成权限系统
    protected function isAgree(){
        if(file_exists(INITCONFIGPATH)){
            $data = include(INITCONFIGPATH);
            if(isset($data['agree'])){
                return $data['agree'];
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    /*
     * @explain 递归写入菜单SQL数据
     */
    protected function recursion($arr,$pid)
    {
        if(is_array($arr) && $arr)
        {
            foreach($arr as $v)
            {
                if(empty($v['ctime']) || !isset($v['ctime'])) $v['ctime'] = $this->now;
                $v['pid'] = $pid;

                if(isset($v['son']))
                {
                    $son = $v['son'];
                    unset($v['son']);
                    Db::name("menu")->insert($v);
                    $id = Db::name("menu")->getLastInsID();
                    $this->recursion($son,$id);
                }else
                {
                    Db::name("menu")->insert($v);
                }
            }
        }
        return false;
    }
    /*
     * @explain 重写开关
     */
    protected function createIsGree()
    {
        $str = "<?php".PHP_EOL;
        $str .= "/**".PHP_EOL;
        $str .= "* @explain 系统生成权限管理 配置文件".PHP_EOL;
        $str .= "*/".PHP_EOL;
        $str .= "return [".PHP_EOL;
        $str .= "    //是否允许初始化系统 false--否，true-是".PHP_EOL;
        $str .= "    'agree' => false".PHP_EOL;
        $str .= "];".PHP_EOL;
        file_put_contents(INITCONFIGPATH,$str);
    }

    /*
     * @explain 拼接创建表SQL
     * @param $table string 表名，$sql string sql语句,[$prefix strting 前缀]
     * @return string 完整的SQL
     */
    protected function joinTableSQL($table,$sql,$prefix='')
    {
        if(empty($table) || empty($sql))
        {
            return "";
        }

        if($prefix) $table = $prefix.$table;

        $sql = "CREATE TABLE IF NOT EXISTS `".$table."`".$sql;
        return $sql;
    }

    /*
     * @explain 查看是否存在表前缀
     * @return string 存在前缀则返回前缀，否则返回空字符串
     */
    protected function getPrefix()
    {
        $re = Db::getConfig("prefix");
        return $re;
    }
}